package com.goktech.commons.db;

import java.util.ArrayList;
import java.util.List;

import com.goktech.commons.utils.StringUtils;

public class SQL {

	private final String FROM = "FROM";
	private final String WHERE = "WHERE";
	private final String LIMIT = "LIMIT";
	private final String ORDER_BY = "ORDER BY";
	private final String GROUP_BY = "GROUP BY";
	private StringBuilder sb = new StringBuilder("SELECT");
	private List<Field> fieldList = new ArrayList<>();
	private List<String> whereList = new ArrayList<>();
	private List<String> groupList = new ArrayList<>();
	private List<String> orderList = new ArrayList<>();
	private int start;
	private int end;

	private String tableName;

	public SQL(String table) {
		this.tableName = table;
	}

	public SQL field(String field, String alias, JdbcType type) {

		this.fieldList.add(new Field(field, alias, null));
		return this;
	}

	public SQL field(String field, String alias) {

		this.fieldList.add(new Field(field, alias, null));
		return this;
	}

	public static class Field {
		private String field;
		private String alias;
		private JdbcType type;

		public Field(String field, String alias, JdbcType type) {
			super();
			this.field = field;
			this.alias = alias;
			this.type = type;
		}

		public String getField() {
			return field;
		}

		public void setField(String field) {
			this.field = field;
		}

		public String getAlias() {
			return alias;
		}

		public void setAlias(String alias) {
			this.alias = alias;
		}

		public JdbcType getType() {
			return type;
		}

		public void setType(JdbcType type) {
			this.type = type;
		}

		@Override
		public String toString() {
			if (StringUtils.isEmpty(alias)) {
				return field;
			}
			return field + " as " + alias;
		}

	}

	public SQL where(String condition) {
		this.whereList.add(condition);
		return this;
	}

	public SQL group(String group) {
		this.groupList.add(group);
		return this;
	}

	public SQL order(String order) {
		this.orderList.add(order);
		return this;
	}

	public SQL limit(int start, int end) {
		this.start = start;
		this.end = end;
		return this;
	}

	public String toString() {
		if (fieldList.size() == 0) {
			sb.append(" ").append("*");
		} else {
			for (Field field : fieldList) {
				sb.append(" ");
				sb.append(field.toString());
				sb.append(",");
			}
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append(" ").append(FROM).append(" ").append(tableName).append("\n");
		if (whereList.size() > 0) {
			sb.append(" ").append(WHERE);
			sb.append(" ").append("1 = 1");
			for (String condition : whereList) {
				sb.append(" ").append(condition);
			}
			sb.append("\n");
		}
		if (groupList.size() > 0) {
			sb.append(" ").append(GROUP_BY);
			for (String group : groupList) {
				sb.append(" ").append(group);
				sb.append(",");
			}
			sb.deleteCharAt(sb.length() - 1).append("\n");
		}
		if (orderList.size() > 0) {
			sb.append(" ").append(GROUP_BY);
			for (String group : orderList) {
				sb.append(" ").append(group);
				sb.append(",");
			}
			sb.deleteCharAt(sb.length() - 1).append("\n");
		}
		if (end != 0 && start != 0) {
			sb.append(LIMIT).append(" ").append(start).append(",").append(end);
		}
		return sb.toString();
	}

	public List<String> getFieldList() {
		List<String> result = new ArrayList<>();
		for (Field field : fieldList) {
			result.add(StringUtils.isEmpty(field.getAlias()) ? field.getField() : field.getAlias());
		}
		return result;
	}
}
